#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "../inc/node.h"
#include "../inc/type.h"

// 颜色定义
#define BLUE "\033[34m"
#define RED "\033[31m"
#define GREEN "\033[32m"
#define RESET "\033[0m"

typedef bool (*cmpfun)(node_t *, node_t *);
/// @brief 初始化和创建新节点
/// @param newdate 输入的新数据
/// @return newnode新节点
node_t *initial(student_t *newdate)
{
    node_t *newnode = calloc(1, sizeof(node_t));
    if (newnode == NULL)
    {
        perror("分配有问题");
    }
    if (newdate != NULL)
    {
        newnode->date = *newdate;
    }
    newnode->next = newnode->prev = newnode;
    return newnode;
}
/// @brief 输入学生信息
/// @return
student_t getnewdate()
{
    student_t student = {0};
    printf("请输入学号 姓名 身高\n");
    while (1)
    {
        if (3 != scanf("%d %31s %f", &student.num,
                       student.name,
                       &student.height))
        {
            while (getchar() != '\n')
                ;
            printf("输入格式有问题请重新输入\n");
            continue;
        }
        break;
    }
    return student;
}

/// @brief 排序这里分三种情况，第一种head->next为空的时候进行头插，第二种是有数据。第三种是最大的时候进行尾插
/// @param head
/// @param newnode
void sort(node_t *head, node_t *newnode)
{
    // 先对新进来节点前后指针进行赋值
    node_t *tmp = {0};
    // 刚开始数据为空的情况,对数据进行头插

    if (head->next == NULL)
    {
        newnode->prev = head;
        newnode->next = head->next;
        head->next->prev = newnode;
        head->next = newnode;
        return;
    }
    // 有数据的情况
    for (tmp = head->next;
         tmp->date.num < newnode->date.num && tmp != head;
         tmp = tmp->next)
        ;
    if (tmp != head)
    {
        // 先对新节点的指向进行修改
        newnode->prev = tmp->prev;
        newnode->next = tmp;
        // 在断开连接
        tmp->prev->next = newnode;
        tmp->prev = newnode;
        return;
    }
    else
    {
        newnode->next = head;
        newnode->prev = head->prev;

        head->prev->next = newnode;
        head->prev = newnode;
        return;
    }
}

/// @brief 显示
/// @param head
void display(node_t *head)
{
    node_t *tmp = head;
    for (tmp = head->next; tmp != head; tmp = tmp->next)
    {
        printf("学号    姓名    身高\n");
        printf("%d\t%s\t%f\n", tmp->date.num, tmp->date.name, tmp->date.height);
    }
}
// 回调函数
bool cmpnum(node_t *pos, node_t *tmp)
{
    return tmp->date.num > pos->date.num;
}
bool cmpheight(node_t *pos, node_t *tmp)
{
    return tmp->date.height > pos->date.height;
}
bool cmpname(node_t *pos, node_t *tmp)
{
    return tmp->date.name[0] > pos->date.name[0];
}

// 对已录入的数据进行排序
void sortcmp(node_t *head, cmpfun cmp)
{
    node_t *min = head->next;
    node_t *pos = NULL;
    node_t *tmp = NULL;
    node_t *tmp1 = NULL;

    while (min != head)
    {
        tmp = min;
        for (pos = min->next; pos != head; pos = pos->next)
        {
            if (cmp(pos, tmp))
            {
                tmp = pos;
            }
        }
        if (tmp != min)
        {
            // 先判断是否相邻
            int i = (min->next == tmp);
            node_t *min_prev = min->prev;
            node_t *min_next = min->next;
            node_t *tmp_prev = tmp->prev;
            node_t *tmp_next = tmp->next;
            if (i)
            {
                min->next = tmp->next;
                min->prev = tmp;
                tmp->next = min;
                tmp->prev = min_prev;

                min_prev->next = tmp;
                tmp_next->prev = min;
            }
            else
            {
                min->next = tmp->next;
                min->prev = tmp->prev;
                tmp->next = min_next;
                tmp->prev = min_prev;

                tmp_prev->next = min;
                tmp_next->prev = min;
                min_prev->next = tmp;
                min_next->prev = tmp;
            }

            // 确保交换后是指向下一个的
            min = tmp->next;
        }
        else // 无交换即继续指向下一个
        {
            min = min->next;
        }
    }
    return;
}

/// @brief 查找
/// @param head
/// @param find1
/// @return
node_t *findcmp(node_t *head, int find1)
{
    node_t *find = head->next;
    switch (find1)
    {
    case 1:
        int num;
        printf("请输入你要查找学号\n");
        scanf("%d", &num);
        for (; find->date.num != num && find != head; find = find->next)
            ;
        if (find == head) // 返回失败
        {
            return NULL;
        }
        else
        { // 找到数据
            return find;
        }
        break;
    case 2:
        char name[32];
        printf("请输入你要查找姓名\n");
        scanf("%31s", name);
        for (; 0 != strcmp(find->date.name, name) && find != head; find = find->next)
            ;
        if (find == head) // 返回失败
        {
            return NULL;
        }
        else
        { // 找到数据
            return find;
        }
        break;
    case 3:
        float height;
        printf("请输入你要查找身高\n");
        scanf("%f", &height);
        for (; find->date.height != height && find != head; find = find->next)
            ;
        if (find == head) // 返回失败
        {
            return NULL;
        }
        else
        { // 找到数据
            return find;
        }
        break;
    default:
        return NULL;
    }
}
/// @brief 删除函数
/// @param del
void delet(node_t *del)
{
    node_t *del_prev = del->prev;
    node_t *del_next = del->next;

    del_prev->next = del->next;
    del_next->prev = del->prev;

    del->prev = del->next = del;
}
// 在 src/print.c 或 src/utils.c 中
void MyPrintf(node_t *node)
{
    if (node == NULL)
    {
        printf("节点为空！\n");
        return;
    }

    // 根据你的数据结构调整
    printf("学号: %d\n", node->date.num);
    printf("姓名: %s\n", node->date.name);
    printf("身高: %.2f\n", node->date.height);
    // 其他字段...
}

/// @brief 随机抽取
/// @param head
/// @return
#if 1
node_t *randcmp(node_t *head)
{
    if (head == NULL || head->next == head)
    {
        printf("链表为空\n");
        return NULL;
    }
    // 初始化随机种子
    static int seeded = 0;
    if (!seeded)
    {
        srand((unsigned int)time(NULL));
        seeded = 1;
    }

    // 获取链表长度
    int length = 0;
    node_t *current = head->next;
    while (current != head)
    {
        length++;
        current = current->next;
    }
    if (length == 0)
    {
        printf("没有学生可抽取\n");
        return NULL;
    }
    printf("开始抽取学生\n");
    printf("共有%d名学生进行抽取\n", length);
    int stop = 30 + rand() % 51; // 随机30-80轮
    int round = 0;
    // 添加变速效果
    int speed_fast = 80000;
    int speed_slow = 100000;
    int point = stop - 10;

    while (1)
    {
        for (node_t *tmp = head->next; tmp != head; tmp = tmp->next)
        {
            // 根据阶段调整速度
            int delay = (round < point) ? speed_fast : speed_slow;
            // 显示当前选中的学生（带颜色效果）
            if (round >= point)
            {
                printf(RED ">>> %s <<<" RESET, tmp->date.name);
            }
            else
            {
                printf(BLUE "%s" RESET, tmp->date.name);
            }

            fflush(stdout);
            usleep(delay);
            // 清空当前行
            printf("\r");
            for (int i = 0; i < 50; i++)
                printf(" ");
            printf("\r");

            round++;
            if (round >= stop)
            {
                // 最终结果显示
                printf("\n" GREEN "🎉 抽取到的学生信息为：" RESET "\n");
                MyPrintf(tmp);

                // 添加一些装饰
                printf(GREEN "═══════════════════════════════════\n" RESET);

                return tmp;
            }
        }
        // 每完成一轮显示进度
        if (round % length == 0)
        {
            int completed_rounds = round / length;
            printf("正在进行第 %d 轮扫描...\r", completed_rounds);
            fflush(stdout);
        }
    }
}
#endif

void destruction(node_t*head,node_t*tmp)
{
   if(tmp==head)
   {
    free(head);
    return;
   }
   destruction(head,tmp->next);
   free(tmp);
   return;

}